package com.cbh.amadeus.client.handler;

import com.cbh.amadeus.client.receiver.component.SubscriberComponent;
import com.cbh.amadeus.client.utils.ChannelReference;
import com.cbh.amadeus.common.enums.MessageType;
import com.cbh.amadeus.common.exception.DuplicateNameException;
import com.cbh.amadeus.common.protocol.AmadeusMessage;
import com.cbh.amadeus.common.protocol.AmadeusMessageWrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;

/**
 * @author ChenBiHui
 * @date 2025/5/1
 */
@Slf4j
@Deprecated
public class DuplicateNameHandler extends SimpleChannelInboundHandler<AmadeusMessageWrap> {

    private final Object monitor = new Object();
    private final SubscriberComponent component;
    private final NioEventLoopGroup work;

    public DuplicateNameHandler(SubscriberComponent component, NioEventLoopGroup work) {
        this.component = component;
        this.work = work;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, AmadeusMessageWrap msg) throws Exception {
        MessageType type = MessageType.find(msg.getType());
        if (type == MessageType.DUPLICATE_NAME) {
            Channel channel = ctx.channel();
            if (channel.isActive()) {
                synchronized (monitor) {
                    if (channel.isActive()) {
                        channel.pipeline().remove(ReconnectHandler.class);
                        channel.close().sync();
                        ChannelReference.remove(channel);
                        AmadeusMessage message = msg.getMessage();
                        throw new DuplicateNameException(
                                "Duplicate register's name [" + component.getConfig().getSubscriberName() + "], " +
                                        "please change another one, " +
                                        "that is exist register's name " + message.getPayload() + ", " +
                                        "please avoid this list"
                        );
                    }
                }
            }
            return;
        }
        ctx.fireChannelRead(msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        if (cause instanceof DuplicateNameException) {
            log.error(cause.getMessage(), cause);
            work.shutdownGracefully()
                    .addListener(item -> System.exit(0));
            return;
        }
        ctx.fireExceptionCaught(cause);
    }
}
